package cn.imokay.juc.cas;

import sun.security.krb5.internal.TGSRep;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 自旋锁案例
 */
public class SpinLockDemo {
    private AtomicReference<Thread> ar = new AtomicReference<>();

    public void lock() {
        Thread thread = Thread.currentThread();
        while (!ar.compareAndSet(null, thread)) {
            //初次获得锁时，compareAndSet操作成功，不会进入循环
        }
    }

    public void unlock() {
        Thread thread = Thread.currentThread();
        ar.compareAndSet(thread, null);
    }

    public static void main(String[] args) {
        SpinLockDemo lockDemo = new SpinLockDemo();
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "\t---启动");
            try {
                TimeUnit.MILLISECONDS.sleep(20);
            } catch (Exception e) {
                e.printStackTrace();
            }
            lockDemo.lock();
            System.out.println(Thread.currentThread().getName() + "\t---获得锁");
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "\t---over");
            System.out.println(Thread.currentThread().getName() + "\t---释放锁");
            lockDemo.unlock();
        }, "t1").start();


        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "\t---启动");
            lockDemo.lock();
            System.out.println(Thread.currentThread().getName() + "\t---获得锁");
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "\t---over");
            System.out.println(Thread.currentThread().getName() + "\t---释放锁");

            lockDemo.unlock();
        }, "t2").start();
    }
}
